﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.Net;
using CYTS.Aoyou.Framework.Context;
using CYTS.Aoyou.Framework.Log;
using CYTS.Aoyou.Framework.Performance.WCFPerformance;
using System.ServiceModel;
using System.Threading;
using CYTS.Aoyou.Framework.Performance;
using CYTS.Aoyou.Framework.Config;

namespace CYTS.Aoyou.Framework.Service
{
    public class WCFServiceInterpector : IDispatchMessageInspector
    {
        #region IDispatchMessageInspector Members

        public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            if (request != null)
            {
                if (request.Version.Envelope.ToString().StartsWith("Soap11") == true ||
                request.Version.Envelope.ToString().StartsWith("Soap12") == true)
                {
                    WebContext context = new WebContext();
                    context.ServerName = Dns.GetHostName();
                    var hostAddress = Dns.GetHostAddresses(context.ServerName);
                    if (hostAddress != null && hostAddress.Length > 1)
                    {
                        context.ServerAddress = hostAddress[1].ToString();
                    }
                    context.ServiceName = request.Headers.To.AbsoluteUri;
                    #region 性能探针
                    var performance = ConfigFactory.GetConfig<PerformanceConfig>();
                    if (performance != null && performance.WCFEnabled)
                    {
                        WCFPerformanceEntity wcfEntity = new WCFPerformanceEntity();
                        try
                        {
                            wcfEntity.ServerAddress = context.ServerAddress;
                            MessageProperties properties = OperationContext.Current.IncomingMessageProperties;
                            RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
                            if (endpoint != null)
                            {
                                wcfEntity.ClientAddress = endpoint.Address;
                                context.ClientAddress = endpoint.Address + ":" + endpoint.Port;
                            }
                            wcfEntity.ExecuteFunName = request.Headers.Action.Substring(request.Headers.Action.LastIndexOf("/") + 1);
                            wcfEntity.InterFaceName = context.ServiceName;
                            wcfEntity.ServerName = context.ServerName;
                            wcfEntity.ServiceType = "WCFPerformance";
                            context.PerformanceEntity = wcfEntity;
                        }
                        catch (Exception ex)
                        {
                            CommonLogger.LogError("性能探针报错", ex);
                        }
                    }
                    #endregion
                    ContextFactory.SetContext((WebContext)context.Clone());
                    MessageLogger.Record(request);
                }
            }

            return request;
        }

        public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            if (reply != null)
            {
                if (reply.Version.Envelope.ToString().StartsWith("Soap11") == true ||
                reply.Version.Envelope.ToString().StartsWith("Soap12") == true)
                {
                    HttpResponseMessageProperty httpResponseProperty = new HttpResponseMessageProperty();
                    httpResponseProperty.Headers.Add(HttpRequestHeader.Connection, "close");
                    reply.Properties[HttpResponseMessageProperty.Name] = httpResponseProperty;

                    //回填上下文
                    WebContext context = ContextFactory.GetContext();
                    MessageLogger.Record(reply);
                    #region 性能探针
                    var performance = ConfigFactory.GetConfig<PerformanceConfig>();
                    if (performance != null && performance.WCFEnabled)
                    {
                        try
                        {
                            WCFPerformanceEntity wcfEntity = context.PerformanceEntity as WCFPerformanceEntity;
                            if (wcfEntity != null)
                            {
                                WCFPerformanceHelper wcfHelper = new WCFPerformanceHelper(context.CallTime);
                                wcfHelper.SetData(wcfEntity);
                            }
                        }
                        catch (Exception ex)
                        {
                            CommonLogger.LogError("性能探针报错", ex);
                        }
                    }
                    #endregion
                    //清空线程槽
                    ContextFactory.SetContext(null);
                }
            }
        }

        #endregion
    }
}
